This CDEF implements a progress bar similar to that used by the Finder and many other programs.
Additionally, by setting the appropriate variation code, instead of the standard progress bar you get the 'barber pole' animation effect.
Other options, set with the appropriated variation codes, include honoring the colors specified in a 'cctb' resource, drawing the control always in the active state ignoring deactivations, and drawing an 'inset' effect around the control as outlined in the develop 15 article "Working in the Third Dimension".
Contents of the Celsius CDEF Folder
-----------------------------------
- CalculateBarBoundary Folder: Symantec C project file, with accompanying C and 68000 Assembly code, and Pascal interface file to the CalculateBarBoundary.Lib library, used by the CelsiusCDEF project
- Celsius CDEF Info: the documentation file you are reading now
- CelsiusCDEF.p: Pascal source code for the Celsius control definition function
- CelsiusCDEF.rsrc: compiled code for any 68K microprocessor of the Celsius control definition function
- CelsiusCDEF.π: THINK Pascal project for compiling the CelsiusCDEF resource
- CelsiusCDEF68020.rsrc: compiled code for 68020-68030-68040 microprocessors of the Celsius control definition function
- CelsiusCDEFStub.p: Pascal source code of the Celsius control definition function, disguised to use any of the provided debugging stubs
How to create a Celsius control
-------------------------------
The file 'Celsius CDEF.rsrc' contains the compiled code of the definition procedure as a resource of type 'CDEF' with ID of 130.
To incorporate the Celsius CDEF in your applications, just open the 'Celsius CDEF.rsrc' file with ResEdit (or any other suitable resource editor), copy the CDEF resource and paste it into your application's resource file.
For creating a progress bar control:
in the resource file of your project create a 'CNTL' resource and put into its ProcID field the number
where kProgressBarID is the ID of the 'CNTL' resource and myWindow is a pointer to one of your windows.
All the other fields in the 'CNTL' template work as usual, except for the control's title, which is always ignored by the definition procedure.
You can also call the NewControl trap, passing it basically the same parameters you enter in the 'CNTL' resource template.
Variation Codes
---------------
A number of possible variation codes can be added to the procID field to obtain special effects. These variation codes are:
0: draw the standard done-to do progress bar
1: draw the barber pole animation (indefinite progress bar)
2: draw using the standard dark gray/steel blue colors, ignoring the colors defined in
any 'cctb' resource
4: draw always the control in the active (enabled) state
8: draw a 3D-like border around the control to obtain an inset effect
You can use any sum of these variation codes, to obtain combinations of the effects described.
See the enclosed demo program for a comparison of all the 16 possible variants.
For example, a Finder-like progress bar would have procID := (130*16) + 2 + 4 = 2086, because is drawn in the standard dark gray / steel blue colors and doesn't get dimmed when its window is put into the background.
How to use a Celsius control
----------------------------
1) Progress bar variation
Let's assume that you're going to perform an operation on some range of items (for example,
copying some user-selected files between two folders). In this case you know how many steps
your operation will take, so you display a window with a Celsius progress bar.
After setting up the control's minimum and maximum to the lower and upper bound of your
range, respectively, simply run the control's value from the lower bound to the upper bound
of the range.
Here's the pseudo-code:
in Pascal
+++++++++
VAR
progressBarHdl: ControlHandle; { obtained via GetNewControl or NewControl }
itemCount, i: SInt16;
BEGIN
{ Set itemCount to the number of items you're going to handle }
SetControlMinimum(progressBarHdl, 1);
SetControlMaximum(progressBarHdl, itemCount);
FOR i := 1 TO itemCount DO BEGIN
SetControlValue(progressBarHdl, i);
DoYourOperation(...);
END;
END;
in C
++++
ControlHandle progressBarHdl; // obtained via GetNewControl or NewControl
SInt16 itemCount, i;
// Set itemCount to the number of items you're going to handle
SetControlMinimum(progressBarHdl, 1);
SetControlMaximum(progressBarHdl, itemCount);
for(i = 1 ; i <= itemCount ;i++ )
{
SetControlValue(progressBarHdl, i);
DoYourOperation(...);
}
2) Barber pole variation
Let's assume that you're going to perform a 'Find All' to search all the occurrences of a
string into a 1.5 MB text document. Obviously you don't know how much time this search will
take, so you display a window with a Celsius barber pole bar. In this case, the frame for
the barber pole animation is taken from the control's value, so all you have to do is keep
changing the control's value.
Here's the pseudo-code:
in Pascal
+++++++++
VAR
barberPoleHdl: ControlHandle; { obtained via GetNewControl or NewControl }
Note that going 'backwards' is supported in all the variations (though I can't imagine how someone would find a use for it)
Part codes
----------
The Celsius CDEF can only return 50 as part code to the TrackControl call.
Color mapping of 'cctb' resources
---------------------------------
When you add 2 to the procID field of the control template, the Celsius CDEF ignores any 'cctb' (control color table) resource that might be attached to the control. To have the Celsius CDEF honor your 'cctb' resource, be sure to NOT add 2 to the procID field. The Celsius CDEF maps the colors defined in your 'cctb' resource as follows:
'cctb' part code Celsius CDEF part
================ =================
Frame color Frame color
Body color To Do part color
Text color Done part color
Thumb color Ignored
Inset border
------------
The border is drawn as specified in the 'Working in the third dimension' article in the issue 15 of the develop journal. The drawing procedure draws the inset effect only if the background color of the window owning the control is the ($EEEE, $EEEE, $EEEE) light gray color; no border is drawn if the window background color is different.
Low memory conditions
---------------------
When the Control Manager sends the initCntl message, the Celsius CDEF allocates a chunk of data and stores it into the contrlData field of the just created control.
First, if there's not enough memory to allocate that data, the contrlData field is set to NIL: in that case the drawing routine exits immediately, without drawing anything.
The offscreen graphics world is created at control's initialization and is kept in memory for the whole lifespan of the control: a progress-bar-like control has, typically, a short lifespan compared to the owning program, so keeping the offscreen world in memory should not cause many problems.
Besides, for the consideration above, creating and destroying the offscreen world at each redraw would mean an unsustainable performance hit.
However, there may be times when the available memory is low, and the offscreen world cannot be created. In these situations the Celsius CDEF draws directly to the control's window, instead of using the offscreen world. Unfortunately, in this case you should expect to see minor 'flicker' effects when drawing; the 'flicker' effects are more evident if the control is drawn in the inactive state.
What happens when...
--------------------
I have a Celsius control with the 3D inset effect and the window intersects a black-&-white screen?
The Celsius CDEF draws the 3D inset effect only on screens with depths of 256 colors or more. On a black-&-white screen the effect cannot be drawn, so we could use even the area of the border. To avoid floating the bar size, however, in the b&w case the outermost one-pixel rectangle is "wasted", i.e. painted with a white pattern.
Compatibility Notes
-------------------
- Kaleidoscope control panel by Greg Landweber, Edward Voas and Amargosa Software
Problem: This control panel (and the 'Aaron' extension) patches the drawing of progress bars
to display a modern, 3D-looking bar. This drawing overrides the Celsius CDEF, but the effect
is lost if the control is inactive: when the Celsius CDEF attempts to dither the progress bar,
it conflicts with the Kaleidoscope patch and creates a very unpleasant drawing, in which you
see only 2 rows of uniformly-spaced dots at the top and bottom of the bar.
Solution: Add 4 as variation code to the procID field of the CNTL template, to always draw
the control in the active state.
Future Directions
-----------------
- Vertical bars
- I will deliberately *not* implement the Apple Grayscale Appearance in the Celsius CDEF. First, there are many other CDEFs and packages that provide it; second, if you really want it, you could implement it by yourself using the Celsius CDEF as a skeleton.